#include "AEPropertyPane.h"

using namespace SP;

BEGIN_EVENT_TABLE( AEPropertyPane, wxPanel )
	EVT_SIZE( AEPropertyPane::OnSize )
	EVT_PG_CHANGED( wxID_ANY, AEPropertyPane::OnPGChange )
END_EVENT_TABLE( )

AEPropertyPane::AEPropertyPane( wxWindow* parent )
	: wxPanel( parent )
{
	m_pPropertyGrid = new wxPropertyGrid( this );


	InitCollisionProperties();
}

void AEPropertyPane::OnSize( wxSizeEvent& event )
{		
	m_pPropertyGrid->SetInitialSize( event.GetSize() );
}

AEPropertyPane::PGCO* AEPropertyPane::AppendCO( wxString name,  SP::SPCollisionObject* pCO )
{
	PGCO* pNew = new PGCO();

	wxPGChoices tarr;
	tarr.Add( L"Box", 1 );
	tarr.Add( L"Sphere", 2 );

	pNew->pCO = pCO;

	wxPGProperty** pProps = pNew->m_PGProperties;
	pProps[0] = m_pPropertyGrid->Append( new wxStringProperty( name ) );
	
	pProps[1] = pProps[0]->AppendChild( new wxEnumProperty( L"Type", wxPG_LABEL, tarr, pCO->m_nCollisionoObjectType ) );
	
	// box
	pProps[2] = pProps[0]->AppendChild( new wxStringProperty( L"Box", wxPG_LABEL, L"<composed>" ) );
	pProps[3] = pProps[2]->AppendChild( new wxStringProperty( L"Center", wxPG_LABEL, L"<composed>" ) );
	pProps[4] = pProps[2]->AppendChild( new wxStringProperty( L"Extents", wxPG_LABEL, L"<composed>" ) );

	pProps[5] = pProps[3]->AppendChild( new wxFloatProperty( L"X" ) );
	pProps[6] = pProps[3]->AppendChild( new wxFloatProperty( L"Y" ) );
	pProps[7] = pProps[3]->AppendChild( new wxFloatProperty( L"Z" ) );

	pProps[8] = pProps[4]->AppendChild( new wxFloatProperty( L"X" ) );
	pProps[9] = pProps[4]->AppendChild( new wxFloatProperty( L"Y" ) );
	pProps[10] = pProps[4]->AppendChild( new wxFloatProperty( L"Z" ) );
	
	// sphere
	pProps[11] = pProps[0]->AppendChild( new wxStringProperty( L"Sphere", wxPG_LABEL, L"<composed>" ) );
	pProps[12] = pProps[11]->AppendChild( new wxFloatProperty( L"Radius" ) );
	pProps[13] = pProps[11]->AppendChild( new wxStringProperty( L"Center", wxPG_LABEL, L"<composed>" ) );

	pProps[14] = pProps[13]->AppendChild( new wxFloatProperty( L"X" ) );
	pProps[15] = pProps[13]->AppendChild( new wxFloatProperty( L"Y" ) );
	pProps[16] = pProps[13]->AppendChild( new wxFloatProperty( L"Z" ) );
	
	if ( pCO->m_nCollisionoObjectType == 1 )
	{
		pProps[11]->Hide( true );
		pProps[2]->Hide( false );

		OrientedBox* pBox = ( OrientedBox* )pCO->m_pCollisionObj;
		pProps[5]->SetValue( pBox->Center.x );
		pProps[6]->SetValue( pBox->Center.y );
		pProps[7]->SetValue( pBox->Center.z );

		pProps[8]->SetValue( pBox->Extents.x );
		pProps[9]->SetValue( pBox->Extents.y );
		pProps[10]->SetValue( pBox->Extents.z );
	}
	else
	{
		pProps[11]->Hide( false );
		pProps[2]->Hide( true );

		Sphere* pSphere = ( Sphere* )pCO->m_pCollisionObj;
		pProps[12]->SetValue( pSphere->Radius );
		pProps[14]->SetValue( pSphere->Center.x );
		pProps[15]->SetValue( pSphere->Center.y );
		pProps[16]->SetValue( pSphere->Center.z );
	}

	return pNew;
}

void AEPropertyPane::UpdateCO( PGCO* pPGCO )
{
	int nType = pPGCO->m_PGProperties[1]->GetValue().GetInteger();

	if ( nType == 1 )
	{
		pPGCO->m_PGProperties[11]->Hide( true );
		pPGCO->m_PGProperties[2]->Hide( false );

		pPGCO->pCO->m_nCollisionoObjectType = 1;

		OrientedBox pNewBox;
		float x, y, z;
		x = pPGCO->m_PGProperties[5]->GetValue().GetDouble();
		y = pPGCO->m_PGProperties[6]->GetValue().GetDouble();
		z = pPGCO->m_PGProperties[7]->GetValue().GetDouble();
		pNewBox.Center = XMFLOAT3( x, y, z );

		x = pPGCO->m_PGProperties[8]->GetValue().GetDouble();
		y = pPGCO->m_PGProperties[9]->GetValue().GetDouble();
		z = pPGCO->m_PGProperties[10]->GetValue().GetDouble();
		pNewBox.Extents = XMFLOAT3( x, y, z );
		
		XMStoreFloat4( &pNewBox.Orientation, XMQuaternionIdentity() );	
		pPGCO->pCO->SetObj( &pNewBox );
	}
	else
	{
		pPGCO->m_PGProperties[11]->Hide( false );
		pPGCO->m_PGProperties[2]->Hide( true );	

		pPGCO->pCO->m_nCollisionoObjectType = 2;

		Sphere pNewSphere;

		pNewSphere.Radius = pPGCO->m_PGProperties[12]->GetValue().GetDouble();
		float x, y, z;
		x = pPGCO->m_PGProperties[14]->GetValue().GetDouble();
		y = pPGCO->m_PGProperties[15]->GetValue().GetDouble();
		z = pPGCO->m_PGProperties[16]->GetValue().GetDouble();
		pNewSphere.Center = XMFLOAT3( x, y, z );

		pPGCO->pCO->SetObj( &pNewSphere );
	}
}

void AEPropertyPane::InitCollisionProperties()
{
	m_pCollisionComponent = AEGetSystem()->GetCollisionComponent();
	//
	m_pPropertyGrid->Clear();
	for ( int i = m_PGCOList.size()-1; i >=0; i-- )
		delete m_PGCOList[i];
	m_PGCOList.clear();

	//
	m_pPropertyGrid->Append(new wxPropertyCategory( L"CollisionComponent" ) );	
	m_PGCOList.push_back( AppendCO( L"Outline                          ", m_pCollisionComponent->m_pOutline ) );

	m_pPropertyGrid->Append(new wxPropertyCategory( L"CollisionObjects" ) );	
	SPCollisionObjectVector objs = m_pCollisionComponent->m_CollisionObjVector;
	m_pCOCount = m_pPropertyGrid->Append( new wxIntProperty( L"NumCollisionObjects", wxPG_LABEL , objs.size() ) );
	for ( int i = 0; i < objs.size(); i++ )
	{
		wxString str = L"CollisionObj[" + wxLongLong(i).ToString() += L"]";
		m_PGCOList.push_back( AppendCO( str, objs[i] ) );
	}
}

void AEPropertyPane::OnPGChange( wxPropertyGridEvent& event )
{
	int count = m_pCOCount->GetValue().GetInteger();
	int size = m_pCollisionComponent->m_CollisionObjVector.size();
	if ( count != size )
	{
		if ( count > size )
		{
			for ( int i = count - size; i > 0; i-- )
			{
				OrientedBox* pBox = new OrientedBox();
				pBox->Center = XMFLOAT3( 0.0f, 0.0f, 0.0f );
				pBox->Extents = XMFLOAT3( 1.0f, 1.0f, 1.0f );
				XMStoreFloat4( &pBox->Orientation, XMQuaternionIdentity() );
				m_pCollisionComponent->m_CollisionObjVector.push_back( new SPCollisionObject( pBox ) );
			}
		}
		else
		{
			for ( int i = size - count; i > 0; i-- )
			{
				delete m_pCollisionComponent->m_CollisionObjVector.back();
				m_pCollisionComponent->m_CollisionObjVector.pop_back();
			}
		}
		InitCollisionProperties();
	}

	for ( int i = 0 ; i < m_PGCOList.size(); i++ )
	{
		UpdateCO( m_PGCOList[i] );
	}
}